#ifndef __MENSAJERO_H_INCLUDED__
#define __MENSAJERO_H_INCLUDED__

#include "cola/Cola.h"
#include "cola/Mensaje.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <iostream>
#include <stdlib.h>

#define ARCHIVO_COLA "/tmp/FiNaval.tmp"

#define COMANDO_DESCONECTAR         2
#define COMANDO_OBTENER_TABLERO     3
#define COMANDO_CONTENIDO_TABLERO   4
#define COMANDO_DISPARO             5
#define COMANDO_MENSAJE             6
#define COMANDO_PASAR_TURNO         7
#define COMANDO_TURNO               8
#define COMANDO_DECIDIR_TURNO       9
#define COMANDO_GANAR               10

#define ID_MASTER       10
#define ID_SLAVE        20

#define COMANDO_LOCAL   1
#define COMANDO_REMOTO  2
#define COMANDO_ERROR   3

class Sistema;

class Mensajero{
private:
	bool master;		/**< Indica si el proceso cumple el
				 * papel de master o slave en la
				 * comunicación. */
	Sistema *sistema;	/**< Sistema de juego al que se asocia
				 * el Mensajero */
	Cola<Mensaje> cola;	/**< Cola de mensajes que comunica los
				 * procesos */

public:
	/** 
	 * Envía un mensaje por la cola de mensajes. Previamente al
	 * envío, el mensaje se marca con un id correspondiente al rol
	 * del pŕoceso en la comunicación (master/slave).
	 *
	 * @param msg El mensaje a enviar por la cola.
	 * 
	 */
	void enviar(Mensaje &msg){
		msg.tipo = (master)?ID_MASTER:ID_SLAVE;
		cola.escribir(msg);
	}

	Mensajero(){
		master = false;
	}

	/** 
	 * Recibe un mensaje del jugador oponente.
	 * 
	 * Nota: Para la recepción se deben buscar mensajes con id
	 * opuesto al del proceso actual (si se es master se reciben
	 * mensajes del slave y viceversa).
	 * 
	 * @return El mensaje obtenido.
	 */
	Mensaje recibir();

	/** 
	 * Se conecta a otro proceso para comenzar el juego.
	 * 
	 * El proceso es el siguiente: 
	 * 
	 *          1) Se crea el archivo que va a utilizarse para
	 *             nombrar la cola.
         *
	 *          2) Se verifica que no exista la cola.
	 *
	 *          3) Si no existe, se crea la cola y el proceso se
	 *             convierte el 'master' de la comunicacion. Caso
	 *             contrario, el proceso solo se conecta y cumple
	 *             el papel de 'slave'.
	 *
	 *          4) El proceso 'master' se queda esperando que
	 *             algun otro proceso se conecte y comience la
	 *             comunicación.
	 *
	 *          5) El 'slave' crea una nueva cola de mensajes
	 *             (creando un nuevo archivo de nombre único) que
	 *             se utilizará para el desarrollo del juego. Esto
	 *             se hace para que solo los dos procesos
	 *             involucrados en el juego se comuniquen sin
	 *             interferencias externas (por ejemplo un tercer
	 *             proceso que se conecta). El 'slave' manda el
	 *             nombre de la cola al 'master'. Una vez
	 *             conectado el 'master' es éste último el que
	 *             comienza la comunicación.
	 * 
	 * @return TRUE si la conexión fue exitosa. Se puede comenzar
	 * el juego.
	 */
	bool conectarse();

	/** 
	 * Produce la desconexión de los procesos. Se cierra la cola
	 * de mensajes.
	 * 
	 */
	void desconectarse();

	bool getMaster(){
		return master;
	}

};

#endif //__MENSAJERO_H_INCLUDED__
